package top.bulk.idgeneration.genertation;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 基于redis实现
 *
 * @author 散装java
 * @date 2024-08-13
 */
@Component("redisIdGen")
@Slf4j
public class RedisIdGen implements IDGen<String> {
    /**
     * 业务类型
     */
    private final Integer bizTpe;
    /**
     * 步长
     */
    private final long delta;
    @Resource
    private RedisTemplate<String, Long> redisTemplate;

    public RedisIdGen() {
        this.bizTpe = 101;
        this.delta = 1;
    }

    public RedisIdGen(Integer bizTpe, Long delta) {
        this.bizTpe = bizTpe;
        this.delta = delta;
    }

    @Override
    public String nextId() {
        // 本示例基于毫秒值生成，也可以基于秒、分钟、天、月、年等生成
        long currentTimeMillis = System.currentTimeMillis();
        // 获取 redis 的 key
        String redisKey = bizTpe + ":" + currentTimeMillis;
        Long sequence = redisTemplate.opsForValue().increment(redisKey, delta);
        // 如果是第一次，则设置时间
        if (sequence != null) {
            if (delta == sequence) {
                redisTemplate.expire(redisKey, 1, TimeUnit.SECONDS);
                log.info("设置过期时间：{}", redisKey);
            }
        } else {
            throw new RuntimeException("redis 生成序列号异常: key" + redisKey);
        }

        // 可以根据自己想要的格式，生成id，默认格式：业务类型 + 时间戳 + 自增序列(4位)
        return String.valueOf(bizTpe) + currentTimeMillis + String.format("%04d", sequence);
    }
}
